import { defineStore } from 'pinia'
import http from '@/core/api'
import { ref } from 'vue'

const replaceUrlParams = (
  url: string,
  params: Record<string, any> = {}
): string => {
  return url.replace(/\{([^}]+)\}/g, (match, key) => {
    return params[key] !== undefined ? params[key] : match
  })
}

const commonConfig = import.meta.glob('@/api-configs/common.ts', {
  eager: true,
})
const commonConfigData =
  commonConfig['/src/api-configs/common.ts']?.default || {}
const apiConfigs = import.meta.glob(
  ['!@/api-configs/common.ts', '@/api-configs/*.ts'],
  {
    eager: true,
  }
)

const getApiName = configKey =>
  configKey.split('/').pop()?.replace('.ts', '') || ''
const useApiStore = defineStore('apiStore', () => {
  const apiStates = ref<
    Record<
      string,
      { loading: boolean; data: any; error: any; defaultValue: any | null }
    >
  >({})

  Object.keys(apiConfigs).forEach(key => {
    const apiName = getApiName(key)
    const {
      default: { defaultValue },
    } = apiConfigs[key]
    apiStates.value[apiName] = {
      loading: false,
      data: defaultValue,
      error: null,
      defaultValue,
    }
  })

  const apiMethods: Record<
    string,
    (params?: any, config?: any) => Promise<any>
  > = {}

  Object.entries(apiConfigs).forEach(([key, { default: config }]) => {
    const apiName = getApiName(key)
    const mergedConfig = { ...commonConfigData, ...config }

    apiMethods[apiName] = async (params?: any, configOverride?: any) => {
      const apiState = apiStates.value[apiName]
      apiState.loading = true
      const processedParam = mergedConfig.transformParam
        ? mergedConfig.transformParam(params)
        : params
      try {
        const processedUrl = replaceUrlParams(mergedConfig.url, processedParam)
        const response = await http[mergedConfig.method](
          processedUrl,
          processedParam,
          configOverride
        )
        apiState.data = mergedConfig.transformResponse
          ? mergedConfig.transformResponse(response)
          : response
        apiState.error = null
        return apiState.data
      } catch (error) {
        console.warn(`${apiName}-error:${error}`)
        apiState.error = error
        apiState.data = mergedConfig.defaultValue
        return mergedConfig.defaultValue
      } finally {
        apiState.loading = false
      }
    }
  })

  return {
    apiStates,
    ...apiMethods,
  }
})

export default useApiStore
